#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <unistd.h>

#include "Logging.h"
#include "ArrayList1.h"

int ArrayListInit(ARRAYLIST *lst,unsigned int max)  // 构造一个空列表
{
    lst->data =(void *)malloc( (size_t)max * sizeof(ITEMDATA) );
    if( lst->data == NULL ) 
    {
        WriteFileLog(LERROR,"Allocate memory error , the ArrayList initialization failed program exits !");
        exit(0);
    }
    #if defined(LINUX)
    if( pthread_mutex_init(&lst->hMutex,NULL) != 0 )
    #else
    if( ( lst->hMutex = CreateMutex(NULL, FALSE, NULL) ) == NULL )
    #endif
    {
        WriteFileLog(LERROR,"Create a mutex lock fails, the program exits !");
        if( lst->data ) 
        {
            free(lst->data);
        }
        exit(0);
    }    
    lst->maxnum = max;
    lst->num    = 0;
    WriteFileLog(LHINT,"Construct an ArrayList is complete !");
    return(1);
}

void ArrayListDestroy(ARRAYLIST *lst)   // 销毁列表
{ 
    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    if( lst->data ) 
    {
        free(lst->data);
    }
    lst->data = NULL;
    lst->num   = 0;

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    #if defined(LINUX)
    pthread_mutex_destroy(&lst->hMutex);
    #else
    CloseHandle(lst->hMutex);
    #endif

    WriteFileLog(LHINT,"ArrayList cleared !");
}

void ArrayListClear(ARRAYLIST *lst)   // 清为空列表
{ 
    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    lst->num   = 0;

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif
}

int ArrayListIsEmpty(ARRAYLIST *lst)   // 若列表为空列表,则返回1,否则返回0 
{
    if( lst->num == 0 ) 
    {
        return(1);
    }
    else
    {
        return(0);
    }
}

int ArrayListLength(ARRAYLIST *lst)   // 返回列表的长度 
{
    return(lst->num);
}

int ArrayListInsert(ARRAYLIST *lst,int fd,int isweb,char *appname,char *ip,unsigned short port)    // 插入列表 
{
    int i,j;

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    if( lst->num > ( lst->maxnum - 1 ) ) 
    {
        #if defined(LINUX)
        pthread_mutex_unlock(&lst->hMutex);
        #else
        ReleaseMutex(lst->hMutex);
        #endif
        WriteFileLog(LERROR,"The client number has reached the maximum allowed, insert failure.");
        return(0);
    }

    for(i=0;i<lst->num;i++)
    {
        if( lst->data[i].fd == fd )
        {
            for(j=i;j<(lst->num-1);j++)
            {
                memcpy(&(lst->data[j]),&(lst->data[j+1]),sizeof(ITEMDATA));
            }
            (lst->num)--;
            shutdown(fd,2); 
            Close(fd);
            #if defined(LINUX)
            pthread_mutex_unlock(&lst->hMutex);
            #else
            ReleaseMutex(lst->hMutex);
            #endif
            WriteFileLog(LFATAL,"The client socket conflict, shut down the existing socket.");
            return(0);
        }
    }

    ITEMDATA dat;
    dat.fd = fd;
    memset(dat.name,0,sizeof(dat.name));
    memset(dat.appname,0,sizeof(dat.appname));
    strcpy(dat.appname,appname);
    memset(dat.channel,0,sizeof(dat.channel));
    memset(dat.program,0,sizeof(dat.program));
    dat.type = 2;
    dat.iswebsocket = isweb;
    dat.logined = 0;
    memset(dat.ip,0,sizeof(dat.ip));
    memcpy(dat.ip,ip,19);
    dat.port = port;
    dat.activetime = GetTimeVal();

    memcpy(&(lst->data[lst->num]),&dat,sizeof(ITEMDATA));
    (lst->num)++;

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    return(1);
}

int  ArrayListDelete(ARRAYLIST *lst,ITEMDATA *dat)   // 删除列表记录 
{
    int i,j;

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    if( (lst->num) < 1 )
    {
        #if defined(LINUX)
        pthread_mutex_unlock(&lst->hMutex);
        #else
        ReleaseMutex(lst->hMutex);
        #endif
        return(0);
    }

    for(i=0;i<lst->num;i++)
    {
        if( memcmp(&(lst->data[i]),dat,sizeof(ITEMDATA)) == 0 )
        {
            for(j=i;j<(lst->num-1);j++)
            {
                memcpy(&(lst->data[j]),&(lst->data[j+1]),sizeof(ITEMDATA));
            }
            (lst->num)--;
            #if defined(LINUX)
            pthread_mutex_unlock(&lst->hMutex);
            #else
            ReleaseMutex(lst->hMutex);
            #endif
            return(1);
        }
        
    }

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    return(0);
}

int ArrayListDeleteByFD(ARRAYLIST *lst,int fd)        // 删除列表记录 
{
    int i,j;

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    if( lst->num < 1 )
    {
        #if defined(LINUX)
        pthread_mutex_unlock(&lst->hMutex);
        #else
        ReleaseMutex(lst->hMutex);
        #endif
        return(0);
    }

    for(i=0;i<lst->num;i++)
    {
        if( lst->data[i].fd == fd )
        {
            for(j=i;j<(lst->num-1);j++)
            {
                memcpy(&(lst->data[j]),&(lst->data[j+1]),sizeof(ITEMDATA));
            }
            (lst->num)--;
            #if defined(LINUX)
            pthread_mutex_unlock(&lst->hMutex);
            #else
            ReleaseMutex(lst->hMutex);
            #endif
            return(1);
        }
        
    }

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    return(0);
}

int ArrayListUpdateActive(ARRAYLIST *lst,int fd)        // 更新记录活动时间
{
    int i;

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    if( lst->num < 1 )
    {
        #if defined(LINUX)
        pthread_mutex_unlock(&lst->hMutex);
        #else
        ReleaseMutex(lst->hMutex);
        #endif
        return(0);
    }

    for(i=0;i<lst->num;i++)
    {
        if( lst->data[i].fd == fd )
        {
            lst->data[i].activetime = GetTimeVal();
            #if defined(LINUX)
            pthread_mutex_unlock(&lst->hMutex);
            #else
            ReleaseMutex(lst->hMutex);
            #endif
            return(1);
        }
    }

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    return(0);
}

int ArrayListUpdateLogin(ARRAYLIST *lst,int fd,char *name,int type,char *channel,char *program,int overwrite,int conflict)        // 更新记录登陆状态
{
    int i;

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    if( lst->num < 1 )
    {
        #if defined(LINUX)
        pthread_mutex_unlock(&lst->hMutex);
        #else
        ReleaseMutex(lst->hMutex);
        #endif
        return(0);
    }

    if( conflict == 0 )
    {
        for(i=0;i<lst->num;i++)
        {
            if( strcmp(lst->data[i].name,name) == 0 )
            {
                if( overwrite == 0 )
                {
                    #if defined(LINUX)
                    pthread_mutex_unlock(&lst->hMutex);
                    #else
                    ReleaseMutex(lst->hMutex);
                    #endif
                    WriteFileLog(LERROR,"The client already exists, login failure.");
                    return(0);
                }
                else
                {
                    char czTemp[1024];
                    strcpy(czTemp,"{\"Name\":\"Exist\",\"Receiver\":\"\",\"Param\":\"\"}");
                    if( lst->data[i].iswebsocket == 0 )
                    {
                        if( TcpSocketWrite(lst->data[i].fd,czTemp,strlen(czTemp)) <= 0 )
                        {
                            shutdown(lst->data[i].fd,2); 
                            Close(lst->data[i].fd);
                            #if defined(LINUX)
                            pthread_mutex_unlock(&lst->hMutex);
                            #else
                            ReleaseMutex(lst->hMutex);
                            #endif
                            WriteFileLog(LERROR,"The client already exists, login failure.");
                            return(0);
                        }
                    }
                    else
                    {
                        if( WebSocketWrite(lst->data[i].fd,czTemp,strlen(czTemp),0) <= 0 )
                        {
                            shutdown(lst->data[i].fd,2); 
                            Close(lst->data[i].fd);
                            #if defined(LINUX)
                            pthread_mutex_unlock(&lst->hMutex);
                            #else
                            ReleaseMutex(lst->hMutex);
                            #endif
                            WriteFileLog(LERROR,"The client already exists, login failure.");
                            return(0);
                        }
                    }
                    WriteFileLog(LERROR,"The client already exists, disconnect the existing client.");
                    #if defined(LINUX)
                    pthread_mutex_unlock(&lst->hMutex);
                    #else
                    ReleaseMutex(lst->hMutex);
                    #endif
                    return(0);
                }
            }
        }
    }

    for(i=0;i<lst->num;i++)
    {
        if( lst->data[i].fd == fd )
        {
            strcpy(lst->data[i].name,name);
            strcpy(lst->data[i].channel,channel);
            strcpy(lst->data[i].program,program);
            lst->data[i].type = type;
            lst->data[i].logined = 1;
            #if defined(LINUX)
            pthread_mutex_unlock(&lst->hMutex);
            #else
            ReleaseMutex(lst->hMutex);
            #endif
            return(1);
        }
    }

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    return(0);
}

int ArrayListDisplay(ARRAYLIST *lst,void (*func)(ARRAYLIST *ls))   // 显示列表
{
    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    (*func)(lst);

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    return 1;
}

char *GetAllDisplayName(ARRAYLIST *lst,char *str)   //获取列表中所有显示大屏的名字列表
{
    int  i;
    char czTemp[2048];

    memset(czTemp,0,sizeof(czTemp));

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    for(i=0;i<lst->num;i++)
    {
        if( lst->data[i].type == 0 )
        {
            if( (strlen(czTemp)+strlen(lst->data[i].name)) > 1024 )
            {
                strcpy(czTemp,"Clients over the length of the queue name.");
                break;                
            }
            strcat(czTemp,"\"");
            strcat(czTemp,lst->data[i].name);
            strcat(czTemp,"\",");
        }
    }

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    if( strlen(czTemp) > 0 )
    {
        czTemp[strlen(czTemp)-1]='\0';
    }
    else
    {
        memset(czTemp,0,sizeof(czTemp));
    }

    strcpy(str,czTemp);

    return(str);
}

int NameToFd(ARRAYLIST *lst,char *name)    //通过名字在列表中查询设备号
{
    int i,ret = 0;

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    for(i=0;i<lst->num;i++)
    {
        if( strcmp(lst->data[i].name,name) == 0 )
        {
            ret = lst->data[i].fd;
            break;
        }
    }

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    return(ret);
}

void  SendMessageToControl(ARRAYLIST *lst,char *str)
{
    int  i,len;

    len = strlen(str);
    if( len <= 0 )
    {
        WriteFileLog(LERROR,"Send meessage to control, message is empty, send is ignored.");
        return;
    }
    if( len > 4096 )
    {
        WriteFileLog(LERROR,"Send meessage to control, message > 4096, send is ignored.");
        return;
    }

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    for(i=0;i<lst->num;i++)
    {
        if( lst->data[i].type == 1 )
        {
            if( lst->data[i].iswebsocket == 0 )
            {
                if( TcpSocketWrite(lst->data[i].fd,str,len) <= 0 )
                {
                    WriteFileLog(LERROR,"Send display information to control(%d) fails",lst->data[i].fd);
                    shutdown(lst->data[i].fd,2); 
                    Close(lst->data[i].fd);
                }
                else
                {
                    WriteFileLog(LHINT,"Send display information to control(%d) success",lst->data[i].fd);
                }
            }
            else
            {
                if( WebSocketWrite(lst->data[i].fd,str,len,0) <= 0 )
                {
                    WriteFileLog(LERROR,"Send display information to control(%d) fails",lst->data[i].fd);
                    shutdown(lst->data[i].fd,2); 
                    Close(lst->data[i].fd);
                }
                else
                {
                    WriteFileLog(LHINT,"Send display information to control(%d) success",lst->data[i].fd);
                }
            }
        }
    }

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

}

int isHotlineClientOn(ARRAYLIST *lst)
{
    int i;

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    for(i=0;i<lst->num;i++)
    {
        if( strstr(lst->data[i].name,"热线电话客户端") )
        {
            #if defined(LINUX)
            pthread_mutex_unlock(&lst->hMutex);
            #else
            ReleaseMutex(lst->hMutex);
            #endif
            return(1);
        }
    }

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif
    return(0);
}

void  SendPingToAll(ARRAYLIST *lst)
{
    int i;
    char str[20];

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    memset(str,0,sizeof(str));
    str[0]=0x89;
    str[1]=0x80;
    str[2]=0x11;
    str[3]=0xc7;
    str[4]=0xa1;
    str[5]=0x7a;
    for(i=0;i<lst->num;i++)
    {
        if( send(lst->data[i].fd, str, 6, 0) <= 0 )
        {
            WriteFileLog(LERROR,"Send ping to client (%d) fails",lst->data[i].fd);
        }
        else
        {
            WriteFileLog(LDEBUG,"Send ping to client (%d) success",lst->data[i].fd);
        }
    }

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

}

void ForwardCommand(ARRAYLIST *lst,int fd,int forward,char *name,char *channel,char *program,char *msg)
{
    int   i,n,len;

    len = strlen(msg);
    if( len <= 0 )
    {
        WriteFileLog(LERROR,"Message content is empty, forwarding is ignored.");
        return;
    }
    if( len > 4096 )
    {
        WriteFileLog(LERROR,"Message content > 4096 , forwarding is ignored.");
        return;
    }

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    n = 0;
    for(i=0;i<lst->num;i++)
    {
        if( fd == lst->data[i].fd )
        {
            continue;
        }
        if( forward == 0 )
        {
            if( strcmp(lst->data[i].name,name) == 0 )
            {
                if( lst->data[i].iswebsocket == 0 )
                {
                    if( TcpSocketWrite(lst->data[i].fd,msg,len) <= 0 )
                    {
                        WriteFileLog(LERROR,"Send message(%d) to client(%s) failed.",len,lst->data[i].name);
                        shutdown(lst->data[i].fd,2); 
                        Close(lst->data[i].fd);
                    }
                    else
                    {
                        WriteFileLog(LHINT,"Send message(%d) to client(%s) success.",len,lst->data[i].name);
                    }
                    n++;
                }
                else
                {
                    if( WebSocketWrite(lst->data[i].fd,msg,len,0) <= 0 )
                    {
                        WriteFileLog(LERROR,"Send message(%d) to client(%s) failed.",len,lst->data[i].name);
                        shutdown(lst->data[i].fd,2); 
                        Close(lst->data[i].fd);
                    }
                    else
                    {
                        WriteFileLog(LHINT,"Send message(%d) to client(%s) success.",len,lst->data[i].name);
                    }
                    n++;
                }
            }
        }
        else if( forward == 1 )
        {
            if( strstr(lst->data[i].name,name) )
            {
                if( lst->data[i].iswebsocket == 0 )
                {
                    if( TcpSocketWrite(lst->data[i].fd,msg,len) <= 0 )
                    {
                        WriteFileLog(LERROR,"Send message(%d) to client(%s) failed.",len,lst->data[i].name);
                        shutdown(lst->data[i].fd,2); 
                        Close(lst->data[i].fd);
                    }
                    else
                    {
                        WriteFileLog(LHINT,"Send message(%d) to client(%s) success.",len,lst->data[i].name);
                    }
                    n++;
                }
                else
                {
                    if( WebSocketWrite(lst->data[i].fd,msg,len,0) <= 0 )
                    {
                        WriteFileLog(LERROR,"Send message(%d) to client(%s) failed.",len,lst->data[i].name);
                        shutdown(lst->data[i].fd,2); 
                        Close(lst->data[i].fd);
                    }
                    else
                    {
                        WriteFileLog(LHINT,"Send message(%d) to client(%s) success.",len,lst->data[i].name);
                    }
                    n++;
                }
            }
        }
        else if( forward == 2 )
        {
            if( lst->data[i].iswebsocket == 0 )
            {
                if( TcpSocketWrite(lst->data[i].fd,msg,len) <= 0 )
                {
                    WriteFileLog(LERROR,"Send message(%d) to client(%s) failed.",len,lst->data[i].name);
                    shutdown(lst->data[i].fd,2); 
                    Close(lst->data[i].fd);
                }
                else
                {
                    WriteFileLog(LHINT,"Send message(%d) to client(%s) success.",len,lst->data[i].name);
                }
                n++;
            }
            else
            {
                if( WebSocketWrite(lst->data[i].fd,msg,len,0) <= 0 )
                {
                    WriteFileLog(LERROR,"Send message(%d) to client(%s) failed.",len,lst->data[i].name);
                    shutdown(lst->data[i].fd,2); 
                    Close(lst->data[i].fd);
                }
                else
                {
                    WriteFileLog(LHINT,"Send message(%d) to client(%s) success.",len,lst->data[i].name);
                }
                n++;
            }
        }
        else if( forward == 3 )
        {
            if( strstr(lst->data[i].name,name) && ( strcmp(lst->data[i].channel,channel) == 0 ) )
            {
                if( lst->data[i].iswebsocket == 0 )
                {
                    if( TcpSocketWrite(lst->data[i].fd,msg,len) <= 0 )
                    {
                        WriteFileLog(LERROR,"Send message(%d) to client(%s) failed.",len,lst->data[i].name);
                        shutdown(lst->data[i].fd,2); 
                        Close(lst->data[i].fd);
                    }
                    else
                    {
                        WriteFileLog(LHINT,"Send message(%d) to client(%s) success.",len,lst->data[i].name);
                    }
                    n++;
                }
                else
                {
                    if( WebSocketWrite(lst->data[i].fd,msg,len,0) <= 0 )
                    {
                        WriteFileLog(LERROR,"Send message(%d) to client(%s) failed.",len,lst->data[i].name);
                        shutdown(lst->data[i].fd,2); 
                        Close(lst->data[i].fd);
                    }
                    else
                    {
                        WriteFileLog(LHINT,"Send message(%d) to client(%s) success.",len,lst->data[i].name);
                    }
                    n++;
                }
            }
        }
        else if( forward == 4 )
        {
            if( strstr(lst->data[i].name,name) && ( strcmp(lst->data[i].program,program) == 0 ) )
            {
                if( lst->data[i].iswebsocket == 0 )
                {
                    if( TcpSocketWrite(lst->data[i].fd,msg,len) <= 0 )
                    {
                        WriteFileLog(LERROR,"Send message(%d) to client(%s) failed.",len,lst->data[i].name);
                        shutdown(lst->data[i].fd,2); 
                        Close(lst->data[i].fd);
                    }
                    else
                    {
                        WriteFileLog(LHINT,"Send message(%d) to client(%s) success.",len,lst->data[i].name);
                    }
                    n++;
                }
                else
                {
                    if( WebSocketWrite(lst->data[i].fd,msg,len,0) <= 0 )
                    {
                        WriteFileLog(LERROR,"Send message(%d) to client(%s) failed.",len,lst->data[i].name);
                        shutdown(lst->data[i].fd,2); 
                        Close(lst->data[i].fd);
                    }
                    else
                    {
                        WriteFileLog(LHINT,"Send message(%d) to client(%s) success.",len,lst->data[i].name);
                    }
                    n++;
                }
            }
        }
    }
    WriteFileLog(LHINT,"Send message %d times to display",n);

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

}

int ArrayListUpdateByInt(ARRAYLIST *lst,int id,ITEMDATA *dat,int (*func)(ARRAYLIST *l,int i,ITEMDATA *d))   // 更新列表 
{
    int ret;
    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    ret = (*func)(lst,id,dat);

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    return(ret);
}

int ArrayListFindByInt(ARRAYLIST *lst,int id,ITEMDATA *dat,int (*func)(ARRAYLIST *l,int i,ITEMDATA *d))   // 查找列表 
{
    int ret;
    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    ret = (*func)(lst,id,dat);

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    return(ret);
}

int ArrayListFind(ARRAYLIST *lst,int n,ITEMDATA *dat)   // 查找列表 
{
    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    if( n > ( lst->maxnum - 1 ) ) 
    {
        #if defined(LINUX)
        pthread_mutex_unlock(&lst->hMutex);
        #else
        ReleaseMutex(lst->hMutex);
        #endif
        return(0);
    }

    memcpy(dat,&(lst->data[n]),sizeof(ITEMDATA));

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    return(1);
}

int ArrayListCallback(ARRAYLIST *lst,int (*func)(ARRAYLIST *l))   // 列表功能回调函数
{
    int ret;

    #if defined(LINUX)
    pthread_mutex_lock(&lst->hMutex);
    #else
    WaitForSingleObject(lst->hMutex, INFINITE);
    #endif

    ret = (*func)(lst);

    #if defined(LINUX)
    pthread_mutex_unlock(&lst->hMutex);
    #else
    ReleaseMutex(lst->hMutex);
    #endif

    return(ret);
}

